﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FGK
{
    class PointLight: Light
    {
        public PointLight(Vector3 position)
        {
            this.position = position;
            this.color = new LightIntensity(1.0, 1.0, 1.0);
        }
        public PointLight(LightIntensity color)
        {
            this.position = new Vector3(0.0f, 0.0f, 0.0f); ;
            this.color = color;
        }
        public PointLight(Vector3 position, LightIntensity color)
        {
            this.position = position;
            this.color = color;
        }
        public override LightIntensity Lighting(Vector3 point, Vector3 lookAt, Primitive p, bool b)
        {
            LightIntensity retColor;
            Vector3 R,L,V,N;
            float dotNL, dotRV;
            double retR=0, retG=0, retB=0, retAmbR=0, retAmbG=0, retAmbB=0;
            retAmbR = (p.material.Ka.r * this.color.r);
            retAmbG = (p.material.Ka.g * this.color.g);
            retAmbB = (p.material.Ka.b * this.color.b);
            if(!b)
            {
                N = p.getNormal(point);
                L = (this.position - point);
                //L = (point - this.position);
                L.normalize();
                V = (lookAt - point);
                V.normalize();
                R = (-L + 2 * N * (N.dot(L)));
                R.normalize();
                //L = (this.position - point);
                //L.normalize();
                dotNL = Math.Max(0.0f, N.dot(L));
                dotRV = Math.Max(0.0f, R.dot(V));
                if (p.material.type == (int)Material.Types.texture)
                {
                    //tu kolor z tekstury tylko jak
                    // 1) punkt przeciecia promienia z obiektem
                    // 2) wsp. punktu z (1) przeliczyć na wsp u,v obiektu (jakos to trzeba bedzie dodac do obiektow - wsp. teksturowania...)
                    //    i to bedzie zalezne od wielkosci obrazka? skad wiemy ile i czy nastepny piksel 
                    // 3) wsp. teksturowania z (2) do rectMapping(u,v) z tekstury materialu daja skladowe do obliczenia koloru
                    LightIntensity texColor;
                    Vector2 uv = p.material.texture.ToUVRect(point.x, point.y);
                    texColor = p.material.texture.rectMapping(uv.x, uv.y);

                    retR = (texColor.r * this.color.r * dotNL + p.material.Ks.r * this.color.r * Math.Pow(dotRV, p.material.Ns));
                    retG = (texColor.g * this.color.g * dotNL + p.material.Ks.g * this.color.g * Math.Pow(dotRV, p.material.Ns));
                    retB = (texColor.b * this.color.b * dotNL + p.material.Ks.b * this.color.b * Math.Pow(dotRV, p.material.Ns));
                }
                else
                {
                    retR = (p.material.Kd.r * this.color.r * dotNL + p.material.Ks.r * this.color.r * Math.Pow(dotRV, p.material.Ns));
                    retG = (p.material.Kd.g * this.color.g * dotNL + p.material.Ks.g * this.color.g * Math.Pow(dotRV, p.material.Ns));
                    retB = (p.material.Kd.b * this.color.b * dotNL + p.material.Ks.b * this.color.b * Math.Pow(dotRV, p.material.Ns));
                }
            }
            retAmbR += (retR > 1.0 ? 1.0 : (retR < 0.0 ? 0.0 : retR));
            retAmbG += (retG > 1.0 ? 1.0 : (retG < 0.0 ? 0.0 : retG));
            retAmbB += (retB > 1.0 ? 1.0 : (retB < 0.0 ? 0.0 : retB));
            retColor = new LightIntensity((retAmbR > 1.0 ? 1.0 : retAmbR), (retAmbG > 1.0 ? 1.0 : retAmbG), (retAmbB > 1.0 ? 1.0 : retAmbB));
            return retColor;
        }
    }
}
